package com.nlecloud.bc.contract;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.fisco.bcos.sdk.abi.FunctionEncoder;
import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
import org.fisco.bcos.sdk.abi.TypeReference;
import org.fisco.bcos.sdk.abi.datatypes.Event;
import org.fisco.bcos.sdk.abi.datatypes.Function;
import org.fisco.bcos.sdk.abi.datatypes.Type;
import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
import org.fisco.bcos.sdk.abi.datatypes.generated.Int256;
import org.fisco.bcos.sdk.abi.datatypes.generated.Int8;
import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.contract.Contract;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.eventsub.EventCallback;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;

@SuppressWarnings("unchecked")
public class User extends Contract {
    public static final String[] BINARY_ARRAY = {"60806040526110066000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005257600080fd5b50604051602080610f088339810180604052810190808051906020019092919050505033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610e01806101076000396000f300608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806334a18dda146100885780633a51d246146100fb578063504ac9821461017857806379fa913f146101cb578063af06bd5b14610234578063bca926af14610279578063d39f70bc14610290575b600080fd5b34801561009457600080fd5b506100f9600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506102a7565b005b34801561010757600080fd5b50610162600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610418565b6040518082815260200191505060405180910390f35b34801561018457600080fd5b506101c960048036038101908080359060200190820180359060200191909192939192939080359060200190820180359060200191909192939192939050505061048d565b005b3480156101d757600080fd5b50610232600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610957565b005b34801561024057600080fd5b5061027760048036038101908080359060200190820180359060200191909192939192939080359060200190929190505050610abf565b005b34801561028557600080fd5b5061028e610c3f565b005b34801561029c57600080fd5b506102a5610c81565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630553904e3084846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561038a57808201518184015260208101905061036f565b50505050905090810190601f1680156103b75780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156103d857600080fd5b505af11580156103ec573d6000803e3d6000fd5b505050506040513d602081101561040257600080fd5b8101908080519060200190929190505050505050565b60006002826040518082805190602001908083835b602083101515610452578051825260208201915060208101905060208303925061042d565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b6000606060009150600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634b40100585856040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825284848281815260200192508082843782019150509350505050600060405180830381600087803b15801561054057600080fd5b505af1158015610554573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250604081101561057e57600080fd5b810190808051906020019092919080516401000000008111156105a057600080fd5b828101905060208101848111156105b657600080fd5b81518560018202830111640100000000821117156105d357600080fd5b5050929190505050809250819350505060008213151561065b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f616d6f756e74206973203000000000000000000000000000000000000000000081525060200191505060405180910390fd5b816002878760405180838380828437820191505092505050908152602001604051809103902054121515156106f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f616d6f756e74206973206e6f7420656e6f75676800000000000000000000000081525060200191505060405180910390fd5b610730826002888860405180838380828437820191505092505050908152602001604051809103902054610cc190919063ffffffff16565b60028787604051808383808284378201915050925050509081526020016040518091039020819055506107d7826002836040518082805190602001908083835b6020831015156107955780518252602082019150602081019050602083039250610770565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902054610d4b90919063ffffffff16565b6002826040518082805190602001908083835b60208310151561080f57805182526020820191506020810190506020830392506107ea565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902081905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a10afce858589896040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200183810383528787828181526020019250808284378201915050838103825285858281815260200192508082843782019150509650505050505050602060405180830381600087803b15801561091357600080fd5b505af1158015610927573d6000803e3d6000fd5b505050506040513d602081101561093d57600080fd5b810190808051906020019092919050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166311e3f2af30836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610a33578082015181840152602081019050610a18565b50505050905090810190601f168015610a605780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b158015610a8057600080fd5b505af1158015610a94573d6000803e3d6000fd5b505050506040513d6020811015610aaa57600080fd5b81019080805190602001909291905050505050565b600060028484604051808383808284378201915050925050509081526020016040518091039020549050818114158015610af95750600081145b15610b92578160028585604051808383808284378201915050925050509081526020016040518091039020819055507fa905c1579e62125537b80aaeec6c4ea71f3c23963dc04e84f0b404d87f623ab46001858585604051808560000b815260200180602001838152602001828103825285858281815260200192508082843782019150509550505050505060405180910390a1610c39565b818114158015610ba3575060008114155b15610c38578160028585604051808383808284378201915050925050509081526020016040518091039020819055507fa905c1579e62125537b80aaeec6c4ea71f3c23963dc04e84f0b404d87f623ab46000858585604051808560000b815260200180602001838152602001828103825285858281815260200192508082843782019150509550505050505060405180910390a15b5b50505050565b610c7f6040805190810160405280601981526020017f73657442616c616e636528737472696e672c696e74323536290000000000000081525060016102a7565b565b610cbf6040805190810160405280601981526020017f73657442616c616e636528737472696e672c696e743235362900000000000000815250610957565b565b600080838313151515610d3c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b82840390508091505092915050565b6000808284019050838112151515610dcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b80915050929150505600a165627a7a7230582003affffc477a31d4102607b06de323819521fa29d91aa3adf53dd1ad2f1bc3010029"};

    public static final String BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", BINARY_ARRAY);

    public static final String[] SM_BINARY_ARRAY = {"60806040526110066000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005257600080fd5b50604051602080610f078339810180604052810190808051906020019092919050505033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610e00806101076000396000f300608060405260043610610082576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168062f0e13314610087578063505deccf146100f057806370ae7e901461016d578063748e7a1b146101b257806394618e4c146101c9578063b4c653e0146101e0578063bf227bc414610253575b600080fd5b34801561009357600080fd5b506100ee600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506102a6565b005b3480156100fc57600080fd5b50610157600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061040e565b6040518082815260200191505060405180910390f35b34801561017957600080fd5b506101b060048036038101908080359060200190820180359060200191909192939192939080359060200190929190505050610483565b005b3480156101be57600080fd5b506101c7610603565b005b3480156101d557600080fd5b506101de610643565b005b3480156101ec57600080fd5b50610251600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610685565b005b34801561025f57600080fd5b506102a46004803603810190808035906020019082018035906020019190919293919293908035906020019082018035906020019190919293919293905050506107f6565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663714c65bd30836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610382578082015181840152602081019050610367565b50505050905090810190601f1680156103af5780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b1580156103cf57600080fd5b505af11580156103e3573d6000803e3d6000fd5b505050506040513d60208110156103f957600080fd5b81019080805190602001909291905050505050565b60006002826040518082805190602001908083835b6020831015156104485780518252602082019150602081019050602083039250610423565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b6000600284846040518083838082843782019150509250505090815260200160405180910390205490508181141580156104bd5750600081145b15610556578160028585604051808383808284378201915050925050509081526020016040518091039020819055507ff5e4edb8e7349ba39651ab1b2e7df3cd0bea46f219ca83ab08867eba95787add6001858585604051808560000b815260200180602001838152602001828103825285858281815260200192508082843782019150509550505050505060405180910390a16105fd565b818114158015610567575060008114155b156105fc578160028585604051808383808284378201915050925050509081526020016040518091039020819055507ff5e4edb8e7349ba39651ab1b2e7df3cd0bea46f219ca83ab08867eba95787add6000858585604051808560000b815260200180602001838152602001828103825285858281815260200192508082843782019150509550505050505060405180910390a15b5b50505050565b6106416040805190810160405280601981526020017f73657442616c616e636528737472696e672c696e7432353629000000000000008152506102a6565b565b6106836040805190810160405280601981526020017f73657442616c616e636528737472696e672c696e7432353629000000000000008152506001610685565b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc536a623084846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561076857808201518184015260208101905061074d565b50505050905090810190601f1680156107955780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156107b657600080fd5b505af11580156107ca573d6000803e3d6000fd5b505050506040513d60208110156107e057600080fd5b8101908080519060200190929190505050505050565b6000606060009150600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346dc11f685856040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018080602001828103825284848281815260200192508082843782019150509350505050600060405180830381600087803b1580156108a957600080fd5b505af11580156108bd573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060408110156108e757600080fd5b8101908080519060200190929190805164010000000081111561090957600080fd5b8281019050602081018481111561091f57600080fd5b815185600182028301116401000000008211171561093c57600080fd5b505092919050505080925081935050506000821315156109c4576040517fc703cb1200000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f616d6f756e74206973203000000000000000000000000000000000000000000081525060200191505060405180910390fd5b81600287876040518083838082843782019150509250505090815260200160405180910390205412151515610a61576040517fc703cb120000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f616d6f756e74206973206e6f7420656e6f75676800000000000000000000000081525060200191505060405180910390fd5b610a99826002888860405180838380828437820191505092505050908152602001604051809103902054610cc090919063ffffffff16565b6002878760405180838380828437820191505092505050908152602001604051809103902081905550610b40826002836040518082805190602001908083835b602083101515610afe5780518252602082019150602081019050602083039250610ad9565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902054610d4a90919063ffffffff16565b6002826040518082805190602001908083835b602083101515610b785780518252602082019150602081019050602083039250610b53565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902081905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cebaa49f858589896040518563ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180806020018060200183810383528787828181526020019250808284378201915050838103825285858281815260200192508082843782019150509650505050505050602060405180830381600087803b158015610c7c57600080fd5b505af1158015610c90573d6000803e3d6000fd5b505050506040513d6020811015610ca657600080fd5b810190808051906020019092919050505050505050505050565b600080838313151515610d3b576040517fc703cb1200000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b82840390508091505092915050565b6000808284019050838112151515610dca576040517fc703cb1200000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b80915050929150505600a165627a7a723058208879dc6ed0aa0ba5855c87677543f29d99bfbe9e76d8768dd65214350b7b441d0029"};

    public static final String SM_BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);

    public static final String[] ABI_ARRAY = {"[{\"constant\":false,\"inputs\":[{\"name\":\"functionName\",\"type\":\"string\"},{\"name\":\"criticalSize\",\"type\":\"uint256\"}],\"name\":\"registerParallelFunction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"userid\",\"type\":\"string\"}],\"name\":\"getBalance\",\"outputs\":[{\"name\":\"amount\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"userid\",\"type\":\"string\"},{\"name\":\"uuid\",\"type\":\"string\"}],\"name\":\"transfer\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"functionName\",\"type\":\"string\"}],\"name\":\"unregisterParallelFunction\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"userid\",\"type\":\"string\"},{\"name\":\"amount\",\"type\":\"int256\"}],\"name\":\"setBalance\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"enableParallel\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"disableParallel\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_c\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_type\",\"type\":\"int8\"},{\"indexed\":false,\"name\":\"_uuid\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"int256\"}],\"name\":\"UserEvent\",\"type\":\"event\"}]"};

    public static final String ABI = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", ABI_ARRAY);

    public static final String FUNC_REGISTERPARALLELFUNCTION = "registerParallelFunction";

    public static final String FUNC_GETBALANCE = "getBalance";

    public static final String FUNC_TRANSFER = "transfer";

    public static final String FUNC_UNREGISTERPARALLELFUNCTION = "unregisterParallelFunction";

    public static final String FUNC_SETBALANCE = "setBalance";

    public static final String FUNC_ENABLEPARALLEL = "enableParallel";

    public static final String FUNC_DISABLEPARALLEL = "disableParallel";

    public static final Event USEREVENT_EVENT = new Event("UserEvent", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Int8>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Int256>() {}));
    ;

    protected User(String contractAddress, Client client, CryptoKeyPair credential) {
        super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
    }

    public static String getBinary(CryptoSuite cryptoSuite) {
        return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
    }

    public TransactionReceipt registerParallelFunction(String functionName, BigInteger criticalSize) {
        final Function function = new Function(
                FUNC_REGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(new Utf8String(functionName),
                new Uint256(criticalSize)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] registerParallelFunction(String functionName, BigInteger criticalSize, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_REGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(new Utf8String(functionName),
                new Uint256(criticalSize)),
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForRegisterParallelFunction(String functionName, BigInteger criticalSize) {
        final Function function = new Function(
                FUNC_REGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(new Utf8String(functionName),
                new Uint256(criticalSize)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple2<String, BigInteger> getRegisterParallelFunctionInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_REGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Uint256>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple2<String, BigInteger>(

                (String) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue()
                );
    }

    public BigInteger getBalance(String userid) throws ContractException {
        final Function function = new Function(FUNC_GETBALANCE, 
                Arrays.<Type>asList(new Utf8String(userid)),
                Arrays.<TypeReference<?>>asList(new TypeReference<Int256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public TransactionReceipt transfer(String userid, String uuid) {
        final Function function = new Function(
                FUNC_TRANSFER, 
                Arrays.<Type>asList(new Utf8String(userid),
                new Utf8String(uuid)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] transfer(String userid, String uuid, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_TRANSFER, 
                Arrays.<Type>asList(new Utf8String(userid),
                new Utf8String(uuid)),
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForTransfer(String userid, String uuid) {
        final Function function = new Function(
                FUNC_TRANSFER, 
                Arrays.<Type>asList(new Utf8String(userid),
                new Utf8String(uuid)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple2<String, String> getTransferInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_TRANSFER, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple2<String, String>(

                (String) results.get(0).getValue(), 
                (String) results.get(1).getValue()
                );
    }

    public TransactionReceipt unregisterParallelFunction(String functionName) {
        final Function function = new Function(
                FUNC_UNREGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(new Utf8String(functionName)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] unregisterParallelFunction(String functionName, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_UNREGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(new Utf8String(functionName)),
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForUnregisterParallelFunction(String functionName) {
        final Function function = new Function(
                FUNC_UNREGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(new Utf8String(functionName)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple1<String> getUnregisterParallelFunctionInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_UNREGISTERPARALLELFUNCTION, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple1<String>(

                (String) results.get(0).getValue()
                );
    }

    public TransactionReceipt setBalance(String userid, BigInteger amount) {
        final Function function = new Function(
                FUNC_SETBALANCE, 
                Arrays.<Type>asList(new Utf8String(userid),
                new Int256(amount)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] setBalance(String userid, BigInteger amount, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_SETBALANCE, 
                Arrays.<Type>asList(new Utf8String(userid),
                new Int256(amount)),
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForSetBalance(String userid, BigInteger amount) {
        final Function function = new Function(
                FUNC_SETBALANCE, 
                Arrays.<Type>asList(new Utf8String(userid),
                new Int256(amount)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple2<String, BigInteger> getSetBalanceInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_SETBALANCE, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Int256>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple2<String, BigInteger>(

                (String) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue()
                );
    }

    public TransactionReceipt enableParallel() {
        final Function function = new Function(
                FUNC_ENABLEPARALLEL, 
                Arrays.<Type>asList(), 
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] enableParallel(TransactionCallback callback) {
        final Function function = new Function(
                FUNC_ENABLEPARALLEL, 
                Arrays.<Type>asList(), 
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForEnableParallel() {
        final Function function = new Function(
                FUNC_ENABLEPARALLEL, 
                Arrays.<Type>asList(), 
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public TransactionReceipt disableParallel() {
        final Function function = new Function(
                FUNC_DISABLEPARALLEL, 
                Arrays.<Type>asList(), 
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] disableParallel(TransactionCallback callback) {
        final Function function = new Function(
                FUNC_DISABLEPARALLEL, 
                Arrays.<Type>asList(), 
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForDisableParallel() {
        final Function function = new Function(
                FUNC_DISABLEPARALLEL, 
                Arrays.<Type>asList(), 
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public List<UserEventEventResponse> getUserEventEvents(TransactionReceipt transactionReceipt) {
        List<EventValuesWithLog> valueList = extractEventParametersWithLog(USEREVENT_EVENT, transactionReceipt);
        ArrayList<UserEventEventResponse> responses = new ArrayList<UserEventEventResponse>(valueList.size());
        for (EventValuesWithLog eventValues : valueList) {
            UserEventEventResponse typedResponse = new UserEventEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse._type = (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
            typedResponse._uuid = (String) eventValues.getNonIndexedValues().get(1).getValue();
            typedResponse.amount = (BigInteger) eventValues.getNonIndexedValues().get(2).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public void subscribeUserEventEvent(String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
        String topic0 = eventEncoder.encode(USEREVENT_EVENT);
        subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
    }

    public void subscribeUserEventEvent(EventCallback callback) {
        String topic0 = eventEncoder.encode(USEREVENT_EVENT);
        subscribeEvent(ABI,BINARY,topic0,callback);
    }

    public static User load(String contractAddress, Client client, CryptoKeyPair credential) {
        return new User(contractAddress, client, credential);
    }

    public static User deploy(Client client, CryptoKeyPair credential, String _c) throws ContractException {
        String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(new org.fisco.bcos.sdk.abi.datatypes.Address(_c)));
        return deploy(User.class, client, credential, getBinary(client.getCryptoSuite()), encodedConstructor);
    }

    public static class UserEventEventResponse {
        public TransactionReceipt.Logs log;

        public BigInteger _type;

        public String _uuid;

        public BigInteger amount;
    }
}
